package com.stx.xhb.customwaterview;


import com.stx.xhb.customwaterview.model.WaterModel;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorGroup;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.agp.render.Canvas;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * @author: xiaohaibin.
 * @time: 2018/1/5
 * @mail:xhb_199409@163.com
 * @github:https://github.com/xiaohaibin
 * @describe: 支付宝蚂蚁森林水滴能量
 */

public class WaterFlake extends StackLayout {
    private static final int WHAT_ADD_PROGRESS = 1;
    private OnWaterItemListener mOnWaterItemListener;
    /**
     * 小树坐标X
     */
    private float treeCenterX = 0;
    /**
     * 小树坐标Y
     */
    private float treeCenterY = 0;
    /**
     * 是否正在收集能量
     */
    private boolean isCollect = false;
    /**
     * view变化的y抖动范围
     */
    private static final int CHANGE_RANGE = 10;
    /**
     * 控制抖动动画执行的快慢
     */
    public static final int PROGRESS_DELAY_MILLIS = 12;
    /**
     * 控制水滴动画的偏移量
     */
    private List<Float> mOffsets = Arrays.asList(5.0f, 4.5f, 4.8f, 5.5f, 5.8f, 6.0f, 6.5f);
    private Random mRandom = new Random();
    private float mWidth;
    private float mHeight;
    private LayoutScatter mLayoutInflater;
    private boolean isDrawed;
    private float offset;

    public WaterFlake(Context context) {
        this(context, null);
    }

    public WaterFlake(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public WaterFlake(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mLayoutInflater = LayoutScatter.getInstance(getContext());
    }

    @Override
    public boolean simulateClick() {
        return super.simulateClick();
    }


    /**
     * Sets model list *
     *
     * @param modelList   model list
     * @param treeCenterX tree center x
     * @param treeCenterY tree center y
     */
    public void setModelList(final List<WaterModel> modelList, float treeCenterX, float treeCenterY) {
        if (modelList == null || modelList.isEmpty()) {
            return;
        }
        this.treeCenterX = treeCenterX;
        this.treeCenterY = treeCenterY;
        removeAllComponents();

    }

    /**
     * Sets model list *
     *
     * @param modelList model list
     * @param view      view
     */
    public void setModelList(final List<WaterModel> modelList, Component view) {
        isDrawed = false;
        if (modelList == null || modelList.isEmpty()) {
            return;
        }
        this.treeCenterX = view.getLeft();
        this.treeCenterY = view.getTop();
        removeAllComponents();
        addWaterView(modelList);

    }

    private void addWaterView(List<WaterModel> modelList) {
        addDrawTask(new DrawTask() {
            @Override
            public void onDraw(Component component, Canvas canvas) {
                mWidth = getEstimatedWidth();
                mHeight = getHeight();
                int[] xRandom = randomCommon(1, 8, modelList.size());
                int[] yRandom = randomCommon(1, 7, modelList.size());
                if (xRandom == null || yRandom == null) {
                    return;
                }

                if (!isDrawed) {
                    for (int i = 0; i < modelList.size(); i++) {
                        WaterModel waterModel = modelList.get(i);
                        final Component view = mLayoutInflater.parse(ResourceTable.Layout_item_water, WaterFlake.this, false);
                        view.setMarginLeft((int) (mWidth * xRandom[i] * 0.11));
                        view.setMarginTop((int) (mHeight * yRandom[i] * 0.08));
                        view.setClickedListener(new ClickedListener() {
                            @Override
                            public void onClick(Component component) {
                                if (mOnWaterItemListener != null) {
                                    mOnWaterItemListener.onItemClick(waterModel);
                                    collectAnimator(view);
                                }
                            }
                        });
                        view.setTag(mRandom.nextBoolean());
                        setOffset(view);
                        addComponent(view);
                        addShowViewAnimation(view);
                        start(view);
                    }

                    isDrawed = true;
                }

            }
        });

    }

    /**
     * 设置小球点击事件  *
     *
     * @param onWaterItemListener onWaterItemListener
     */
    public void setOnWaterItemListener(OnWaterItemListener onWaterItemListener) {
        mOnWaterItemListener = onWaterItemListener;
    }

    /**
     * On water item listener
     */
    public interface OnWaterItemListener {
        void onItemClick(WaterModel waterModel);
    }

    private void collectAnimator(final Component view) {
        if (isCollect) {
            return;
        }
        isCollect = true;
        AnimatorProperty translatAnimatorY = view.createAnimatorProperty();
        translatAnimatorY.moveToY(mHeight);
        setStateChangedListener(view, translatAnimatorY);
        AnimatorProperty translatAnimatorX = view.createAnimatorProperty();
        translatAnimatorX.moveToX(100);
        AnimatorProperty alphaAnimator = view.createAnimatorProperty();
        alphaAnimator.alphaFrom(1);
        alphaAnimator.alpha(0);
        AnimatorGroup animatorSet = new AnimatorGroup();
        animatorSet.runParallel(translatAnimatorY, translatAnimatorX, alphaAnimator);
        animatorSet.setDuration(3000);
        animatorSet.start();
    }

    private void setStateChangedListener(Component view, AnimatorProperty translatAnimatorY) {
        translatAnimatorY.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {

            }

            @Override
            public void onCancel(Animator animator) {

            }

            @Override
            public void onEnd(Animator animator) {
                removeComponent(view);
                isCollect = false;
            }

            @Override
            public void onPause(Animator animator) {

            }

            @Override
            public void onResume(Animator animator) {

            }
        });
    }


    /**
     * Start *
     *
     * @param view view
     */
    public void start(Component view) {
        boolean isUp = (boolean) view.getTag();
        AnimatorProperty mAnimator = view.createAnimatorProperty();
        if (isUp) {
            int top = view.getMarginTop();
            mAnimator.moveFromY(top - offset).moveToY(top + offset);
            mAnimator.moveFromY(top + offset).moveToY(top - offset);
        } else {
            int top = view.getMarginTop();
            mAnimator.moveFromY(top + offset).moveToY(top - offset);
            mAnimator.moveFromY(top - offset).moveToY(top + offset);
        }
        mAnimator.setDuration(1800);
        mAnimator.setCurveType(Animator.CurveType.LINEAR);
        mAnimator.setLoopedCount(Integer.MAX_VALUE);
        mAnimator.start();
    }


    /**
     * 添加显示动画 *
     *
     * @param view view
     */
    private void addShowViewAnimation(Component view) {
        AnimatorProperty animator = view.createAnimatorProperty();
        animator.alphaFrom(0).alpha(1).scaleXFrom(0).scaleX(1).scaleYFrom(0).scaleY(1).setDuration(500).start();
    }


    /**
     * Random common int [ ]
     *
     * @param min min
     * @param max max
     * @param numCount   n
     * @return the int [ ]
     */
    public static int[] randomCommon(int min, int max, int numCount) {
        if (numCount > (max - min + 1) || max < min) {
            return null;
        }
        int[] result = new int[numCount];
        int count = 0;
        while (count < numCount) {
            int num = (int) ((Math.random() * (max - min)) + min);
            boolean flag = true;
            for (int j = 0; j < numCount; j++) {
                if (num == result[j]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                result[count] = num;
                count++;
            }
        }
        return result;
    }


    public float getTreeCenterX() {
        return treeCenterX;
    }

    public float getTreeCenterY() {
        return treeCenterY;
    }

    /**
     * 设置View的offset *
     *
     * @param view view
     */
    private void setOffset(Component view) {
        offset = mOffsets.get(mRandom.nextInt(mOffsets.size()));
    }

}
